package com.kang.nanohttpddemo.webserver

import android.content.Context
import android.util.Log
import com.google.gson.Gson
import com.kang.nanohttpddemo.R
import fi.iki.elonen.NanoHTTPD
import fi.iki.elonen.NanoWSD
import fi.iki.elonen.NanoWSD.WebSocketFrame.CloseCode
import java.io.IOException
import java.io.InputStream
import java.security.KeyStore
import javax.net.ssl.KeyManagerFactory


/**
 * Date: 2022/4/21
 * Author: SunBinKang
 * Description:
 */
class WebSocketSecureServer(hostname: String?, port: Int) : NanoWSD(hostname, port) {//继承NanoHTTPD

    private val TAG = "binkang"
    private var count = 0 //用于记录请求为第几次
    private var mGson: Gson = Gson() //用于记录请求为第几次

    //注释一下这段代码就是http server,加上就是https server,但是是自签名的证书
    //服务器信任的客户端证书
    constructor(context: Context, hostname: String?, port: Int) : this(hostname, port) {
        //从文件中拿到流对象
        val keystoreStream: InputStream =
            context.resources.openRawResource(R.raw.server)
        //拿到keystore对象
        val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
        //keystore加载流对象，并把storepass参数传入
        keyStore.load(keystoreStream, "password".toCharArray())
        val keyManagerFactory =
            KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
        //这里的第二个参数就是密钥密码，keypass
        keyManagerFactory.init(keyStore, "password".toCharArray())
        //调用 NanoHttpd的makeSecure()方法
        makeSecure(makeSSLSocketFactory(keyStore, keyManagerFactory), null)
    }

    override fun openWebSocket(handshake: IHTTPSession): WebSocket {
        return DebugWebSocket(this, handshake)
    }

    private class DebugWebSocket(server: WebSocketSecureServer, handshakeRequest: IHTTPSession?) :
        WebSocket(handshakeRequest) {
            private val TAG = "DebugWebSocket"
        private val server: WebSocketSecureServer

        init {
            this.server = server
        }

        override fun onOpen() {
            Log.d(TAG, "onOpen")
            Thread() {
                run {
                    kotlin.runCatching {
                        while (isOpen) {
                            ping("ping".toByteArray())
                            Thread.sleep(30000)
                        }
                    }
                }
            }.start()
        }
        override fun onClose(code: CloseCode, reason: String, initiatedByRemote: Boolean) {
                Log.d(TAG,
                    "C [" + (if (initiatedByRemote) "Remote" else "Self") + "] " + (code
                        ?: "UnknownCloseCode[$code]")
                            + if (reason != null && !reason.isEmpty()) ": $reason" else ""
                )
        }

        override fun onMessage(message: WebSocketFrame) {
            Log.d(TAG, "onMessage")
            try {
                message.setUnmasked()
                sendFrame(message)
            } catch (e: IOException) {
                throw RuntimeException(e)
            }
        }

        override fun onPong(pong: WebSocketFrame) {
            Log.d(TAG,"P $pong")
        }

        override fun onException(exception: IOException) {
            Log.d(TAG, "exception occured", exception)
        }

        override fun debugFrameReceived(frame: WebSocketFrame) {
            Log.d(TAG,"R $frame")

        }

        override fun debugFrameSent(frame: WebSocketFrame) {
            Log.d(TAG,"S $frame")
        }
    }

}